home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-09-08 | 9.8 KB | 429 lines | [TEXT/MWPS] |
- {************************************************************}
- {* This is a quick program to demonstrate hiding the menu}
- {* bar in Pascal.}
- {*}
- {* Written by Bill Catambay, 8/24/95.}
- {*}
- {* This program hides the menu bar and creates a window which}
- {* occupies the menu bar space (as well as the rest of the screen).}
- {* It then animates a ball across the screen to demonstrate writing}
- {* over the menu bar. }
- {*}
- {* It uses the sine wave function to animate the ball, and performs a "warp"}
- {* when the ball hits the end (and slows the ball down and plays a sound for effect.}
- {* It also continues the ball in the correct location from the wrap rather than }
- {* starting it in the same place. This was a bit tricky, but not too complicated. }
- {*}
- {* 9/8/95: Fixed the ball to no longer flicker using offscreen worlds. Added}
- {* compiler directives to get program to work in both CodeWarrior and Think Pascal. }
- {*}
- {* Send all comments to catambay@aol.com}
- {* }
- {*************************************************************}
- Program HideMenuBar;
-
- {$IFC UNDEFINED THINK_PASCAL}
- Uses
- Fonts, Windows, Dialogs, ToolUtils, Resources, LowMem, QDOffscreen, SegLoad, Fp, Sound;
-
- {$ELSEC}
- Uses
- QDOffscreen, Sound;
-
- Type
- WindowRef = WindowPeek;
- {$ENDC}
-
- Const
- width = 20;
- height = 20;
- kResourceSoundComplete = 1;
- kHandleSoundComplete = 2;
-
- Var
- save_mbar,i: integer;
- mBarRgn: rgnHandle;
- gBackWind: WindowPtr;
- gForeWind: WindowPtr;
- GrayRgn: RgnHandle;
- newPos,oldPos: point;
- newBox,oldBox: rect;
- mainRect: rect;
- err: OSErr;
- ticks: longint;
- deskPat: PixPatHandle;
- savePat: GworldPtr;
- y,k,pi: real;
- SndChan: SndChannelPtr;
- InPlay: boolean;
- SndChanStat: SCStatus;
- MySound: Handle;
- wrapping: boolean;
-
- {$IFC UNDEFINED THINK_PASCAL}
- Procedure InitToolbox;
-
- begin
- initGraf(@qd.thePort);
- initFonts;
- initWindows;
- initMenus;
- TEinit;
- initDialogs(nil);
- MaxApplZone;
- InitCursor;
- end;
-
- {$ELSEC}
- Function LMGetWindowList: WindowRef;
- Inline
- $2EB8, $09D6; { MOVE.l $09D6,(SP) }
-
- Function GetMBarHeight: INTEGER;
- Inline
- $3EB8, $0BAA; { MOVE.w $0BAA,(SP) }
-
- Function LMGetMBarHeight: Integer;
- Inline
- $3EB8, $0BAA; { MOVE.w $0BAA,(SP) }
-
- Procedure LMSetMBarHeight (value: Integer);
- Inline
- $31DF, $0BAA; { MOVE.w (SP)+,$0BAA }
-
- Function LMGetGrayRgn: RgnHandle;
- Inline
- $2EB8, $09EE; { MOVE.l $09EE,(SP) }
-
- {$ENDC}
-
- Procedure SH_ForceUpdate(rgn: RgnHandle);
-
- Var
- wpFirst: WindowRef;
-
- begin
- wpFirst := LMGetWindowList;
- PaintBehind(wpFirst, rgn);
- CalcVisBehind(wpFirst, rgn);
- end;
-
- Procedure GetMBarRgn(mbarRgn: RgnHandle);
-
- Var
- mbarRect: Rect;
-
- begin
- {$IFC UNDEFINED THINK_PASCAL}
- mBarRect := qd.screenBits.bounds;
- {$ELSEC}
- mBarRect := screenBits.bounds;
- {$ENDC}
- mBarRect.bottom := mBarRect.top + save_mbar;
- RectRgn(mBarRgn, mBarRect);
- end;
-
- Function CenterWind(srect,mainrect: rect): rect;
-
- Var
- wrect: rect;
-
- begin
- wrect.top := (mainrect.bottom - mainrect.top - (srect.bottom -
- srect.top)) div 2 + mainrect.top;
- wrect.bottom := wrect.top + (srect.bottom - srect.top);
- wrect.left := (mainrect.right - mainrect.left - (srect.right -
- srect.left)) div 2 + mainrect.left;
- wrect.right := wrect.left + (srect.right - srect.left);
- CenterWind := wrect;
- end; { of centerwind }
-
- Procedure PlayAsyncCallback (chan: SndChannelPtr; cmd: SndCommand);
-
- begin
- InPlay := FALSE;
- end;
-
- Procedure SoundDispose;
-
- Var
- i: integer;
-
- begin
- if SndChan <> nil then
- begin
- Err := SndDisposeChannel(SndChan, True);
- SndChan := nil;
- inPlay := false;
- end;
- end;
-
- Procedure ResetMbar;
-
- begin
- LMSetMBarHeight(save_mbar);
- DiffRgn(GrayRgn, mBarRgn, GrayRgn); { remove the menu bar from the desktop }
- DisposeRgn(mBarRgn); { dispose the bar region }
- DrawMenuBar;
- end;
-
- Procedure ExitError;
-
- begin
- ResetMbar;
- ExitToShell;
- end;
-
- Procedure BackgroundSound;
-
- Var
- MySndCmd: SndCommand;
- SndHeaderPtr: SoundHeaderPtr;
- i: integer;
- {$IFC UNDEFINED THINK_PASCAL}
- sndUPP: SndCallBackUPP;
- {$ENDC}
-
- begin
- {$IFC UNDEFINED THINK_PASCAL}
- sndUPP := NewSndCallBackProc(@PlayAsyncCallback);
- Err := SndNewChannel(SndChan, sampledSynth, 0, sndUPP);
- {$ELSEC}
- Err := SndNewChannel(SndChan, sampledSynth, 0, @PlayAsyncCallback);
- {$ENDC}
- if err <> NoErr then
- exit(BackgroundSound);
- if SndChan = NIL then
- exit(BackgroundSound);
- HLock(mysound);
- {$IFC UNDEFINED THINK_PASCAL}
- Err := SndPlay(SndChan, SndListHandle(mySound), True);
- {$ELSEC}
- Err := SndPlay(SndChan, mySound, True);
- {$ENDC}
- if err <> NoErr then
- exit(BackgroundSound);
- InPlay := TRUE;
- with mySndCmd do
- begin
- cmd := callBackCmd;
- param1 := 0;
- param2 := 0;
- end;
- Err := SndDoCommand(SndChan, mySndCmd, False);
- HUnlock(mysound);
- end;
-
- Procedure RemoveMbar;
-
- begin
- save_mbar := GetMBarHeight;
- mBarRgn := NewRgn;
- GetMBarRgn(mBarRgn); { make a region for the mbar }
- LMSetMBarHeight(0);
- GrayRgn := LMGetGrayRgn;
- UnionRgn(GrayRgn,mBarRgn,GrayRgn);
- SH_ForceUpdate(mBarRgn);
- end;
-
- Procedure SetBackground;
-
- Var
- r: rect;
-
- begin
- {$IFC UNDEFINED THINK_PASCAL}
- gBackWind := NewCwindow(Nil, qd.screenBits.bounds, '', FALSE, documentProc,
- Pointer(-1), TRUE, 0);
- UnionRect(GrayRgn^^.rgnBBox, qd.screenBits.bounds, r);
- {$ELSEC}
- gBackWind := NewCwindow(Nil, screenBits.bounds, '', FALSE, documentProc,
- Pointer(-1), TRUE, 0);
- UnionRect(GrayRgn^^.rgnBBox, screenBits.bounds, r);
- {$ENDC}
- MoveWindow(gBackWind, r.left, r.top, false);
- SizeWindow(gBackWind, r.right-r.left+width, r.bottom-r.top, true);
- BeginUpdate(gBackWind);
- ShowWindow(gBackWind);
- SetPort(gBackWind);
- { we want to set the origin of the window to be the origin }
- { of the global coordinate system so that the pattern we }
- { draw is not offset from the desktop's pattern }
- SetOrigin(GrafPtr(gBackWind)^.portRect.left,GrafPtr(gBackWind)^.portRect.top);
- r := gBackWind^.portRect;
- FillCRect(r,GetPixPat(16)); { so use the 'ppat'=16 resource in system }
- SetOrigin(0,0);
- EndUpdate(gBackWind);
- end;
-
- Procedure SetForeground;
-
- Var
- r: rect;
-
- begin
- SetRect(r,0,0,400,100);
- {$IFC UNDEFINED THINK_PASCAL}
- r := CenterWind(r, qd.screenBits.bounds);
- {$ELSEC}
- r := CenterWind(r, screenBits.bounds);
- {$ENDC}
- gForeWind := NewCwindow(NIL, r, '', TRUE, plainDbox, Pointer(-1),TRUE,0);
- SetPort(gForeWind);
- moveTo(20,20);
- textsize(24);
- DrawString('Look Mom! No menu bar!');
- moveTo(100,50);
- textsize(10);
- DrawString('Pascal sample by Bill Catambay');
- moveTo(100,65);
- DrawString('catambay@aol.com');
- moveTo(50,90);
- textsize(12);
- DrawString('<press mouse button to quit>');
- end;
-
- {$IFC UNDEFINED THINK_PASCAL}
- {$ELSEC}
- Function Acos(radians: real): real;
-
- begin
- acos := 3.14159265359; { Defined only for radians = -1 }
- end;
-
- Function Remainder(n,k: real): real;
-
- Var
- m: integer;
-
- begin
- m := trunc(n / k);
- remainder := n - m * k;
- end;
- {$ENDC}
-
- Procedure InitGlobals;
-
- Var
- r,s: rect;
- saveGD: GDHandle;
- saveGW: GWorldPtr;
-
- begin
- SetPt(oldPos,0,50+trunc(50*sin(0/20)));
- SetRect(oldBox,oldPos.h,oldPos.v,oldPos.h+width,oldPos.v+height);
- SetRect(r,0,0,gBackWind^.portRect.right,200);
- GetGWorld(saveGW,saveGD);
- {$IFC UNDEFINED THINK_PASCAL}
- Err := newGWorld(savePat,0,r,NIL,NIL,0);
- {$ELSEC}
- Err := newGWorld(savePat,0,r,NIL,NIL,[]);
- {$ENDC}
- if Err <> noErr then
- ExitToShell;
- if not LockPixels(savepat^.portPixMap) then
- ExitToShell;
- SetGWorld(savepat,NIL);
- SetRect(r,0,0,gBackWind^.portRect.right-width,200);
- CopyBits(gBackWind^.portbits,GrafPtr(savePat)^.portBits,r,r,srcCopy,NIL);
- SetRect(r,gBackWind^.portRect.right-width,0,gBackWind^.portRect.right,200);
- SetRect(s,0,0,width,200);
- CopyBits(gBackWind^.portbits,GrafPtr(savePat)^.portBits,s,r,srcCopy,NIL);
- UnlockPixels(savePat^.portPixMap);
- SetGWorld(saveGW,saveGD);
- SetPort(gBackWind);
- k := 0;
- pi := acos(-1);
- mysound := GetNamedResource('snd ','Wrap');
- wrapping := false;
- end;
-
- Procedure DrawBall;
-
- Var
- saveGD: GDHandle;
- saveGW: GWorldPtr;
- offRect: rect;
- tmpRect: rect;
- delta: point;
- offscreen: gworldPtr;
- wrap: boolean;
-
- begin
- newPos.h := oldPos.h + 2;
- y := 50 + 50*sin((newPos.h+k)/30);
- newPos.v := trunc(y);
- if newPos.h > gBackWind^.portRect.right - width then
- begin
- k := remainder(newPos.h + k,pi * 60);
- newPos.h := 0;
- y := 50 + 50*sin((newPos.h+k)/30);
- newPos.v := trunc(y);
- end;
- wrap := (newPos.h <= gBackWind^.portRect.right - width) and
- (newPos.h + width > gBackWind^.portRect.right - width);
- if wrap and (not wrapping) then
- begin
- SoundDispose;
- BackgroundSound;
- wrapping := true;
- end
- else if wrapping and (not wrap) then
- wrapping := false;
- SetRect(newBox,newPos.h,newPos.v,newPos.h+width,newPos.v+height);
- UnionRect(newBox,oldBox,mainRect);
- GetGWorld(saveGW,saveGD);
- { mainRect top and left now become the offsets since newGworld sets offscreen starting at 0,0 }
- delta.h := mainRect.left;
- delta.v := mainRect.top;
- offrect := mainRect;
- offsetRect(offrect,-delta.h,-delta.v);
- {$IFC UNDEFINED THINK_PASCAL}
- Err := newGWorld(offscreen,0,offrect,NIL,NIL,0);
- {$ELSEC}
- Err := newGWorld(offscreen,0,offrect,NIL,NIL,[]);
- {$ENDC}
- if Err <> noErr then
- ExitError;
- if not LockPixels(offscreen^.portPixMap) then
- ExitError;
- SetGWorld(offscreen,NIL);
- CopyBits(grafptr(savepat)^.portbits,grafptr(offscreen)^.portbits,mainRect,offRect,srcCopy,NIL);
- tmpRect := newBox;
- OffsetRect(tmpRect,-delta.h,-delta.v);
- {$IFC UNDEFINED THINK_PASCAL}
- FillOval(tmpRect, qd.black);
- {$ELSEC}
- FillOval(tmpRect, black);
- {$ENDC}
- SetGWorld(saveGW,saveGD);
- SetPort(gBackWind);
- CopyBits(grafptr(offscreen)^.portbits,gBackWind^.portBits,offRect,mainRect,srcCopy,NIL);
- if wrap then
- begin
- tmpRect := mainRect;
- OffsetRect(tmpRect,width-gBackWind^.portRect.right,0);
- CopyBits(grafPtr(offscreen)^.portbits,gBackWind^.portBits,offRect,tmpRect,srcCopy,NIL);
- end;
- UnlockPixels(offscreen^.portPixMap);
- DisposeGworld(offscreen);
- oldPos := newPos;
- oldBox := newBox;
- if wrap then
- Delay(1,ticks);
- end;
-
- begin
- {$IFC UNDEFINED THINK_PASCAL}
- InitToolbox;
- {$ENDC}
- RemoveMbar;
- SetBackground;
- SetForeground;
- InitGlobals;
- SetPort(gBackWind);
- repeat
- DrawBall;
- until button;
- ResetMbar;
- end.